<!--
 * @Author: Ylong
 * @Date: 2025-07-16 16:12:40
 * @LastEditTime: 2025-08-12 23:32:20
-->
<template>
  <div class="monitor">
    <div class="filter"></div>
    <div class="result">
      <div class="table-part">
        <el-table
          v-loading="loading"
          :data="result.rows"
          stripe
          style="width: 100%; height: 100%"
        >
          <el-table-column
            v-for="header in tableHeaders"
            :key="header.prop"
            :prop="header.prop"
            :label="header.label"
            :min-width="header.width"
          >
            <template #default="scope">
              <span v-if="header.prop === 'inline_status'">
                <el-tag
                  :type="fmtStatus(scope.row.userId) ? 'success' : 'danger'"
                  >{{ fmtStatus(scope.row.userId) ? "在线" : "离线" }}</el-tag
                >
              </span>
              <span v-else>
                {{ scope.row[header.prop] }}
              </span>
            </template>
          </el-table-column>

          <el-table-column fixed="right" label="操作" min-width="100">
            <template #default="scope">
              <el-button
                link
                type="primary"
                size="small"
                @click="handlePlayVideo(scope.row)"
              >
                实时视频
              </el-button>
            </template>
          </el-table-column>
        </el-table>
      </div>

      <div class="pagination">
        <el-pagination
          v-model:current-page="result.page.pageNo"
          v-model:page-size="result.page.pageSize"
          :page-sizes="[10, 20, 50, 100]"
          layout="total, sizes, prev, pager, next, jumper"
          :total="result.total"
          @size-change="getPageData"
          @current-change="getPageData"
        >
        </el-pagination>
      </div>
    </div>
    <!-- <div ref="videoRef" class="admin-video"></div> -->

    <el-dialog
      v-model="dialog.visible"
      title="实时视频"
      width="800"
      draggable
      :before-close="dialogClose"
    >
      <div class="dialog-options">
        <el-button
          v-if="!dialog.isOffline && userDevices[dialog.userId]"
          size="small"
          >摄像头：{{ userDevices[dialog.userId] }}个</el-button
        >
        <el-button
          v-if="!dialog.isOffline"
          :type="dialog.switch ? 'primary' : 'default'"
          size="small"
          :icon="Switch"
          circle
          @click="changeCamera"
        >
        </el-button>
      </div>
      <div style="width: 100%; height: 580px">
        <div
          v-if="!dialog.isOffline"
          v-loading="dialog.loading"
          ref="remoteRef"
          id="remote-video"
        ></div>
        <el-result
          style="width: 100%; position: absolute; top: 20%; left: 0"
          icon="info"
          title="Offline"
          v-else
        >
          <template #sub-title>
            <p>当前用户已离线</p>
          </template>
        </el-result>
      </div>
    </el-dialog>
  </div>
</template>

<script setup lang="ts">
import { computed, onBeforeUnmount, onMounted, reactive, ref } from "vue";
import { GetMonitorList } from "../../../services/base.api";
import useTRTC from "../../../hooks/useTRTC";
import { Switch } from "@element-plus/icons-vue";
import { useAccountStore } from "../../../stores/account";

const accountStore = useAccountStore();

const TRTC = useTRTC();

const remoteRef = ref<HTMLDivElement>();

const loading = ref(true);

const dialog = reactive({
  visible: false,
  switch: false,
  userId: "",
  loading: false,
  isOffline: false,
});

const tableHeaders = [
  { prop: "account", label: "账户", width: "120" },
  { prop: "username", label: "用户名", width: "120" },
  { prop: "inline_status", label: "状态", width: "120" },
];

// 列表数据
const result = reactive({
  page: {
    pageNo: 1,
    pageSize: 10,
  },
  rows: [] as any[],
  total: 0,
});

// 记录在线用户id
const inlineIds = ref<
  {
    userId: string;
    streamType: string;
  }[]
>([]);
const userDevices = reactive<any>({});

// 格式化状态
const fmtStatus = computed(() => {
  inlineIds;
  return (userId: string) => {
    return inlineIds.value.find((id) => id.userId === userId);
  };
});

/**
 * 获取页面数据
 */
const getPageData = () => {
  loading.value = true;
  GetMonitorList({ ...result.page }).then((res) => {
    const { total, users } = res.data;
    result.rows = users;
    result.total = total;
    setTimeout(() => {
      loading.value = false;
    }, 300);
  });
};

/**
 * 播放远端视频
 * @param userId 用户ID
 */
const playRemoteVideo = (user: { userId: string; streamType: string }) => {
  setTimeout(() => {
    TRTC.trtc
      .startRemoteVideo({
        userId: user.userId,
        streamType: user.streamType,
        view: remoteRef.value,
      })
      .then(() => {
        const id = inlineIds.value.find((id) => id.userId === user.userId);
        if (!id) {
          inlineIds.value.push(user);
        }
        // 播放远端音频
        TRTC.trtc.muteRemoteAudio(user.userId, false);
      })
      .catch(() => {
        inlineIds.value = inlineIds.value.filter(
          (id) => id.userId !== user.userId
        );
        dialog.isOffline = true;
      })
      .finally(() => {
        setTimeout(() => {
          dialog.loading = false;
        }, 300);
      });
  });
};

// 点击查看实时视频
const handlePlayVideo = (row: any) => {
  dialog.visible = true;
  dialog.loading = true;
  dialog.isOffline = false;
  dialog.userId = row.userId;
  let user = inlineIds.value.find((id) => id.userId === row.userId);
  if (!user) {
    user = {
      userId: row.userId,
      streamType: TRTC.TYPE.STREAM_TYPE_SUB,
    };
  }
  playRemoteVideo(user);
  TRTC.trtc.sendCustomMessage({
    cmdId: 1,
    data: new TextEncoder().encode("deviceCount").buffer,
  });
};

const changeCamera = () => {
  dialog.switch = !dialog.switch;
  TRTC.trtc.sendCustomMessage({
    cmdId: 1,
    data: new TextEncoder().encode("switchDevice").buffer,
  });
};

const dialogClose = () => {
  dialog.visible = false;
  const user = inlineIds.value.find((id) => id.userId === dialog.userId);
  if (user) {
    TRTC.trtc.stopRemoteVideo({
      userId: user.userId,
      streamType: user.streamType,
    });
    // 停止远端音频
    TRTC.trtc.muteRemoteAudio(dialog.userId, true);
  }
};

const getUser = (userId: string) => {
  return result.rows.find((item) => item.userId === userId);
};

onMounted(() => {
  getPageData();
  // TRTC.init("administrator", null);

  // 监听远端用户上线，远端用户发布了视频
  TRTC.trtc.on(
    TRTC.EVENT.REMOTE_VIDEO_AVAILABLE,
    ({ userId, streamType }: any) => {
      console.log(
        "-------------------REMOTE_VIDEO_AVAILABLE :>> ",
        userId,
        streamType
      );
      // 停止远端音频
      TRTC.trtc.muteRemoteAudio(userId, true);

      if (dialog.visible) {
        if (userId === dialog.userId) {
          dialog.isOffline = false;
          playRemoteVideo({ userId, streamType });
        }
      }
      inlineIds.value.push({
        userId,
        streamType,
      });
    }
  );
  // 监听远端用户下线，远端停止发布视频
  TRTC.trtc.on(TRTC.EVENT.REMOTE_VIDEO_UNAVAILABLE, ({ userId }: any) => {
    console.log("-------------------REMOTE_VIDEO_UNAVAILABLE :>> ", userId);
    if (dialog.visible) {
      if (userId === dialog.userId) {
        dialog.isOffline = true;
        dialog.switch = false;
      }
    }
    inlineIds.value = inlineIds.value.filter((id) => id.userId !== userId);
  });

  // receive custom message
  TRTC.trtc.on(TRTC.EVENT.CUSTOM_MESSAGE, (event: any) => {
    // event.userId: 远端发消息的 userId
    // event.cmdId: 您自定义的消息 Id
    // event.seq: 消息的序号
    // event.data: 消息内容，ArrayBuffer 类型
    const { userId, data } = event;
    const msg = new TextDecoder().decode(data);
    const user = getUser(userId);
    console.log("----CUSTOM_MESSAGE :>> ", msg, user.account);
    if (msg.startsWith("DEVICES_")) {
      const devices = msg.split("_");
      userDevices[userId] = devices[1];
    }
  });

  TRTC.init(accountStore.account.account, null);
});

onBeforeUnmount(() => {
  TRTC.destroy();
});
</script>

<style scoped lang="scss">
.monitor {
  width: 100%;
  height: 100%;
  position: relative;

  .result {
    width: 100%;
    height: 100%;
    display: flex;
    flex-direction: column;
    justify-content: space-between;

    .table-part {
      display: flex;
      height: calc(100% - 52px);
      max-height: calc(100% - 52px);
      flex: 1 1 auto;
    }

    .pagination {
      flex: 0 0 32px;
      height: 32px;
      margin-top: 20px;
      display: flex;
      justify-content: flex-end;
    }
  }

  .admin-video {
    position: absolute;
    bottom: 20px;
    left: 20px;
    width: 300px;
    height: 300px;
    box-shadow: 0 0 10px 0 rgba(0, 0, 0, 0.1);
    z-index: 2;
  }

  :deep(.el-dialog__body) {
    padding: 0 14px;

    .dialog-options {
      position: absolute;
      top: 10px;
      right: 60px;
    }

    #remote-video {
      width: 100%;
      min-height: 400px;
      height: 100%;
      position: relative;

      video {
        width: auto !important;
        max-width: 100%;
        height: 100%;
        position: absolute;
        top: 50%;
        left: 50%;
        transform: translate(-50%, -50%);
        object-fit: cover;
      }
    }
  }
}
</style>
